package com.dognessnetwork.operation.configurer;


import java.lang.reflect.Method;
import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


@Aspect
@Component
public class TestAspect {

	private static final Logger log = LoggerFactory.getLogger(TestAspect.class);

	@Pointcut("execution(public * com.dognessnetwork.operation.controller.*.*(..)) && @annotation(com.dognessnetwork.operation.configurer.MyAnnotation)")
	public void addAdvice() {
	}

	@Before("addAdvice()")
    public void before(JoinPoint joinPoint){
       MethodSignature sign =  (MethodSignature)joinPoint.getSignature();
       Method method = sign.getMethod();
       MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
       System.out.print("打印："+annotation.value()+" 开始前");
    }    
    @Around("addAdvice()")
    public Object advice(ProceedingJoinPoint joinPoint) throws Throwable{
    	log.info("\n通知之开始");
        Object proceed=null;
        // 获取session中的用户
     	HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
     				.getRequest();
     	
		// 获取请求的ip
		// 获取执行的方法名

		// 获取方法执行前时间
		proceed = joinPoint.proceed();
		// 提取controller中ExecutionResult的属性

		log.info("\n------------------------------------Request log---------------------------------------------");
		log.info("\n| description: " + getControllerMethodDescription(joinPoint).getDescription());

		Object[] params = joinPoint.getArgs();
		String returnStr = Arrays.toString(params);

		log.info("\n| url: " + request.getRequestURI());
		log.info("\n| ip: " + request.getRemoteHost());
		log.info("\n| Params: " + returnStr);
		log.info("\n| Response: " + proceed);
		return proceed;
    }

    @After("addAdvice()")
    public void after() {
    	log.info("\nafter方法执行后");
    }
    
    /***
	 * 获取controller的操作信息
	 * 
	 * @param point
	 * @return
	 */
	public LoggerDto getControllerMethodDescription(ProceedingJoinPoint point) throws Exception {
		// 获取连接点目标类名
		String targetName = point.getTarget().getClass().getName();
		// 获取连接点签名的方法名
		String methodName = point.getSignature().getName();
		// 获取连接点参数
		Object[] args = point.getArgs();
		// 根据连接点类的名字获取指定类
		@SuppressWarnings("rawtypes")
		Class targetClass = Class.forName(targetName);
		// 获取类里面的方法
		Method[] methods = targetClass.getMethods();
		LoggerDto loggerDto = new LoggerDto();
		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				@SuppressWarnings("rawtypes")
				Class[] clazzs = method.getParameterTypes();
				if (clazzs.length == args.length) {
					loggerDto.setDescription(method.getAnnotation(MyAnnotation.class).value());
					break;
				}
			}
		}

		return loggerDto;
	}
}
